<?php


namespace app\common\command;

use app\common\model\user\Openvpn;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Log;
use think\facade\Db;


class OpenvpnStatus extends Command
{
    protected function configure()
    {
        $this->setName('openvpn_status')
            ->setDescription('openvpn 状态');
    }


    protected function execute(Input $input, Output $output)
    {
        try {
            // 读取文件
            $filename = '/etc/openvpn/openvpn-status.log';
            $lines = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

            $section = '';
//            Db::execute('TRUNCATE TABLE dw_openvpn');

            foreach ($lines as $line) {
                echo $line . " : \n";
                if (strpos($line, 'Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since') !== false) {
                    $section = 'clients';
                    continue;
                } elseif (strpos($line, 'Virtual Address,Common Name,Real Address,Last Ref') !== false) {
                    $section = 'routes';
                    continue;
                } elseif (strpos($line, 'ROUTING TABLE') !== false) {
                    $section = '';
                    continue;
                } elseif (empty(trim($line)) || $line[0] === '#' || strpos($line, 'ROUTING TABLE') !== false
                    || strpos($line, 'GLOBAL STATS') !== false) {
                    $section = '';
                    continue;
                }

                if ($section === 'clients') {
                    list($commonName, $realAddress, $bytesReceived, $bytesSent, $connectedSince) = explode(',', $line);
                    $timestamp = strtotime($connectedSince);
                    if (substr($commonName, 0, 5) != 'drcom') {
                        file_put_contents('/tmp/openvpn_error.log', $line . PHP_EOL, FILE_APPEND);
                        continue;
                    }
                    try{
                        //存在$commonName则更新，否则插入数据
                        $row =[
                            'common_name' => $commonName,
                            'ext_ip' => explode(':', $realAddress)[0],
                            'rx_bytes' => $bytesReceived,
                            'tx_bytes' => $bytesSent,
                            'create_time' => $timestamp,
                        ];
                        $openvpn = new Openvpn();
                        $openvpn->duplicate($row)
                            ->insert($row);


                    } catch (\Exception $e) {
                        file_put_contents('/tmp/openvpn_error.log', $e->getMessage() . PHP_EOL, FILE_APPEND);
                    }
                } elseif ($section === 'routes') {
                    list($virtualAddress, $commonName, $realAddress, $lastRef) = explode(',', $line);
                    $timestamp = strtotime($lastRef);
                    Openvpn::where('common_name', $commonName)
                        ->update([
                            'vpn_ip' => $virtualAddress,
                            'update_time' => $timestamp,
                        ]);
                }
            }

            // 调用方法更新状态
            if(date('H') == '06'){
                Openvpn::updateStatus();
            }

            echo "done!" . PHP_EOL;
            return true;
        } catch (\Exception $e) {
            Log::write('openvpn_status,失败原因:' . $e->getMessage());
            return false;
        }
    }


}